﻿using DomenModel;
using Infrastructure.Repositories;
using Model.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;


namespace Infrastructure.Service
{
    public class AdministratorService : IAdministratorService 
    {
        UserRealization _dbUsers = new UserRealization();

        public User GetUser(string loginName)
        {
            var user = _dbUsers.GetByLogin(loginName);
            return user;
        }

        public List<Role> GetRoles()
        {
            RoleRealization _dbRole = new RoleRealization();
            var roles = _dbRole.GetCollection();
            return roles;

        }

        public List<User> GetPaginationListOfUsers(int page, int itemsOnPage, string orderUsersBy)
        {
            Expression<Func<User, string>> predicate;
           // List<User> paginationListOfUser;
            
            switch (orderUsersBy)
            {
                case "UserName":
                    predicate = p => p.LoginName;
                    break;
                case "FirstName":
                    predicate = p => p.FirstName;
                    break;
                case "LastName":
                    predicate = p => p.LastName;
                    break;
                case "Role":
                    predicate = p => p.Role.Name;
                    break;
                case "Email":
                    predicate = p => p.Email;
                    break;
                case "Region":
                    predicate = p => p.Region;
                    break;
                default:
                    predicate = p => p.LoginName;
                    break;
            } 
            var list = _dbUsers.GetListForPagination(page, itemsOnPage,predicate);
            return list;
        }

        public List<User> GetPaginationWithFilter(int page, int itemsOnPage, string orderUsersBy, string searchString, string listSelectField, string listSelectCondition)
        {
            Expression<Func<User, string>> predicateSortBy;
            switch (orderUsersBy)
            {
                case "UserName":
                    predicateSortBy = p => p.LoginName;
                    break;
                case "FirstName":
                    predicateSortBy = p => p.FirstName;
                    break;
                case "LastName":
                    predicateSortBy = p => p.LastName;
                    break;
                case "Role":
                    predicateSortBy = p => p.Role.Name;
                    break;
                case "Email":
                    predicateSortBy = p => p.Email;
                    break;
                case "Region":
                    predicateSortBy = p => p.Region;
                    break;
                default:
                    predicateSortBy = p => p.LoginName;
                    break;
            } 

            var param = Expression.Parameter(typeof(User), "u");
            MemberExpression prop;
            switch (listSelectField)
            {
                case "User Name":
                    prop = Expression.Property(param, typeof(User).GetProperty("LoginName"));
                    break;

                case "First Name":
                    prop = Expression.Property(param, typeof(User).GetProperty("FirstName"));
                    break;

                case "Last Name":
                    prop = Expression.Property(param, typeof(User).GetProperty("LastName"));
                    break;

                default:
                    prop = Expression.Property(param, typeof(User).GetProperty("LoginName"));
                    break;
            }

            string selectedCondition;
            switch (listSelectCondition)
            {
                case "starts with":
                    selectedCondition = "StartsWith";
                    break;

                case "equals":
                    selectedCondition = "Equals";
                    break;

                case "contains":
                    selectedCondition = "Contains";
                    break;

                default:
                    selectedCondition = "Contains";
                    break;
            }

            MethodCallExpression startsWith = Expression.Call( 
                prop,
                typeof(String).GetMethod(selectedCondition, new Type[] { typeof(String) }), 
                Expression.Constant(searchString)
                );

          
            var filterExpression = Expression.Lambda<Func<User, bool>>(startsWith, param);


            var list = _dbUsers.GetListForPaginationWithFilter(page, itemsOnPage, filterExpression , predicateSortBy);
            return list;

        }
       
        /*public int GetCountOfUser()
        {
            UserRealization _dbUsers = new UserRealization();
            var count = _dbUsers.GetUserCount();
            return count;


        } */

    }

}
